﻿#include "ssVector.h"
#include "ssAssert.h"

namespace StarSeeker
{
/////////////////////////////////ssFLOAT3X////////////////////////////////
ssFLOAT3X::ssFLOAT3X(void)
{
	x = y = z = 0.f;
}
ssFLOAT3X::ssFLOAT3X(ssfloat fx, ssfloat fy, ssfloat fz)
{
	x = fx;
	y = fy;
	z = fz;
}
ssFLOAT3X::ssFLOAT3X(const ssFLOAT3X &sf3)
{
	x = sf3.x;
	y = sf3.y;
	z = sf3.z;
}
void ssFLOAT3X::operator=(const ssFLOAT3X &sf3)
{
	x = sf3.x;
	y = sf3.y;
	z = sf3.z;
}

ssFLOAT3X::operator ssfloat* ()
{
	return m;
}
ssFLOAT3X::operator const ssfloat* () const
{
	return m;
}

void ssFLOAT3X::Set(ssfloat fx, ssfloat fy, ssfloat fz)
{
	x = fx;
	y = fy;
	z = fz;
}
void ssFLOAT3X::Set(const ssfloat *fVal)
{
	x = fVal[0];
	y = fVal[1];
	z = fVal[2];
}
void ssFLOAT3X::Zero()
{
	x = y = z = 0.f;
}
//近似0向量
bool ssFLOAT3X::IsZero(ssfloat eps)
{
	return (Math3D::Abs(x)<eps && Math3D::Abs(y)<eps && Math3D::Abs(z)<eps);
}
//两个向量近似相等
bool ssFLOAT3X::IsApproximate(const ssFLOAT3X& val, ssfloat eps)
{
	return (Math3D::Abs(x - val.x)<eps && Math3D::Abs(y - val.y)<eps && Math3D::Abs(z - val.z)<eps);
}
//取反
void ssFLOAT3X::Against()
{
	x = -x;
	y = -y;
	z = -z;
}
//求模
ssfloat ssFLOAT3X::Length() const
{
	return Math3D::Sqrt(x*x + y*y + z*z);
}
//求模的平方
ssfloat ssFLOAT3X::SquaredLength() const
{
	return x * x + y * y + z * z;
}
//单位化
void ssFLOAT3X::Normalize()
{
	ssfloat len = Length();
	SS_ASSERT(len != 0.0f);
	if (len != 0.0f)
	{
		x /= len;
		y /= len;
		z /= len;
	}
}
ssFLOAT3X ssFLOAT3X::Normalized() const
{
	ssFLOAT3X ret(*this);
	ret.Normalize();
	return ret;
}
//点乘
ssfloat ssFLOAT3X::Dot(const ssFLOAT3X& val) const
{
	return x*val.x + y*val.y + z*val.z;
}
//叉乘
ssFLOAT3X ssFLOAT3X::Cross(const ssFLOAT3X& val) const
{
	return ssFLOAT3X(y*val.z - val.y*z, z*val.x - x*val.z, x*val.y - y*val.x);
}
//模近似0
bool ssFLOAT3X::IsZeroLength() const
{
	return (x*x + y*y + z*z < Math3D::gc_EPSILON_E6*Math3D::gc_EPSILON_E6);
}

ssFLOAT3X ssFLOAT3X::operator + ( const ssFLOAT3X& val ) const
{
	return ssFLOAT3X(x+val.x, y+val.y, z+val.z);
}
ssFLOAT3X ssFLOAT3X::operator - ( const ssFLOAT3X& val ) const
{
	return ssFLOAT3X(x-val.x, y-val.y, z-val.z);
}
ssFLOAT3X ssFLOAT3X::operator*(const ssFLOAT3X & val) const
{
	return ssFLOAT3X(x * val.x, y * val.y, z * val.z);
}
ssFLOAT3X ssFLOAT3X::operator/(const ssFLOAT3X & val) const
{
	SS_ASSERT(val.x != 0.0f && val.y != 0.0f && val.z != 0.0f);
	if (val.x != 0.0f && val.y != 0.0f && val.z != 0.0f)
		return ssFLOAT3X(x / val.x, y / val.y, z / val.z);
	else
		return ssFLOAT3X(0, 0, 0);
}
ssFLOAT3X ssFLOAT3X::operator+(ssfloat val) const
{
	return ssFLOAT3X(x+val, y+val, z+val);
}
ssFLOAT3X ssFLOAT3X::operator-(ssfloat val) const
{
	return ssFLOAT3X(x-val, y-val, z-val);
}
ssFLOAT3X ssFLOAT3X::operator * ( ssfloat val ) const
{
	return ssFLOAT3X(x*val, y*val, z*val);
}
ssFLOAT3X ssFLOAT3X::operator / ( ssfloat val ) const
{
	SS_ASSERT(val != 0.0f);
	if (val != 0.0f)
		return ssFLOAT3X(x / val, y / val, z / val);
	else
		return ssFLOAT3X(0,0,0);
}

void ssFLOAT3X::operator += ( const ssFLOAT3X& val)
{
	x += val.x;
	y += val.y;
	z += val.z;
}
void ssFLOAT3X::operator -= ( const ssFLOAT3X& val)
{
	x -= val.x;
	y -= val.y;
	z -= val.z;
}
void ssFLOAT3X::operator*=(const ssFLOAT3X & val)
{
	x *= val.x;
	y *= val.y;
	z *= val.z;
}
void ssFLOAT3X::operator/=(const ssFLOAT3X & val)
{
	SS_ASSERT(val.x != 0.0f && val.y != 0.0f && val.z != 0.0f);
	if (val.x != 0.0f && val.y != 0.0f && val.z != 0.0f)
	{
		x /= val.x;
		y /= val.y;
		z /= val.z;
	}
}
void ssFLOAT3X::operator *= ( ssfloat val)
{
	x *= val;
	y *= val;
	z *= val;
}
void ssFLOAT3X::operator /= ( ssfloat val)
{
	SS_ASSERT(val!=0.0f);
	if (val != 0.0f)
	{
		x /= val;
		y /= val;
		z /= val;
	}
}

bool ssFLOAT3X::operator == ( const ssFLOAT3X& val ) const
{
	if (x==val.x && y==val.y && z==val.z)
		return true;
	else
		return false;
}
bool ssFLOAT3X::operator != ( const ssFLOAT3X& val ) const
{
	if (x!=val.x || y!=val.y || z!=val.z)
		return true;
	else
		return false;
}
///////////////////////////////////////////////////////////////////////////
}
